<template>
  <div class="home">
    <div>
      <h4> 1. Test of ref + v-model </h4>
      <div> name: {{ name }} </div>
      <span>v-model绑定：</span>
      <input type="text" v-model="name"/>
    </div>
    <div>
      <h4> 2. Test of reactive </h4>
      <div>
        {{ count.a }} + {{ count.b }} = {{ count.a + count.b }}
      </div>
      <button @click="addA">Add A</button>
      <button @click="addB">Add B</button>
    </div>
    <div>
      <h4> 3. Test of appState. 
        <a href="https://gitee.com/Yubi233/md_note/blob/master/Js&Ts/%E7%AE%80%E6%98%93%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86%E5%B7%A5%E5%85%B7/index.md">
          The store introduction.
        </a> 
      </h4>
      <div>
        {{ appState.appName }}
      </div> 
      <div>
        <span>触发@change：</span>
        <input type="text" :value="appState.appName" @change="changeAppName($event)"/>
      </div>
    </div>
    <div>
      <h4> 4. Test of prop </h4>
      <!-- 父组件改变，子组件中的prop也会改变 -->
      <test-prop :propValue="propValue"></test-prop>
      <span>v-model绑定：</span>
      <input type="text" v-model="propValue" />
    </div>
    <div>
      <h4> 5. Test of prop and toRaw(fail: cause ref)</h4>
      <test-prop :propValue="propValueRaw"></test-prop>
      <span>v-model绑定：</span>
      <input type="text" v-model="propValueRaw" />
    </div>
    <div>
      <h4> 6. Test of appState and toRaw. 
      </h4>
      <div>
        {{ appState.appName }}
      </div> 
      <div>
        <!-- <input type="text" :value="appStateRaw.appName" @change="changeAppName($event)"/> -->
        <button @click="changeAppNameRaw"> change appNameRaw </button>
        <button @click="changeAppNameNoRaw"> change appName </button>
      </div>
    </div>
    <div>
      <h4> 7. Test of reactive and toRaw </h4>
      <div>
        {{ countRaw.a }} + {{ countRaw.b }} = {{ countRaw.a + countRaw.b }}
      </div>
      <button @click="addARaw">Add A</button>
      <button @click="addARaw">Add B</button>
    </div>
    <div>
      <h4> 8. Test of normalValue and markRaw</h4>
      <div>
        {{ normalValue.text }}
      </div>
      <input type="text" v-model="normalValue.text" @change="log('normalValue.text: ' + normalValue.text)"/>
    </div>
    <!-- 我以为这样会提醒一下 test.a或者.b，但是没有-->
    <!-- {{ test. }} -->
    <div>
      <h4> 9. Test of prop and markRaw</h4>
      <test-prop :propValue="normalValue.text"></test-prop>
      <span>v-model绑定：</span>
      <input type="text" v-model="normalValue.text" />
    </div>
  </div>
</template>

<script lang="ts">

import { defineComponent, getCurrentInstance, markRaw, onMounted, onUnmounted, onUpdated, reactive, ref, SetupContext, toRaw } from 'vue';
import { appModule } from '@/store/app';
import TestProp from '@/components/TestProp/index.vue';
import { useRouter } from 'vue-router';

export default defineComponent({ components: { TestProp },
  data(){
  },
  setup(props: any, context: SetupContext ) {
    
    
    console.log(context);

    const that = {
      name: ref('name1'),
      count: reactive({
        a: 1,
        b: 2,
      }),
      appState: appModule.state,
      propValue: ref('value'),
      normalValue: markRaw({
        text: 'raw text',
      }) 
    };

    const methods = {
      addA() {
        that.count.a++;
      },
      addB() {
        that.count.b++;
      },
      addARaw() {
        raw.countRaw.a++;
        console.log('countRaw.a：' + raw.countRaw.a);
      },
      addBRaw() {
        raw.countRaw.b++;
        console.log('countRaw.b：' + raw.countRaw.b);
      },
      changeAppName(event: any) {
        appModule.setAppName(event.target.value);
      },
      changeAppNameNoRaw() {
        that.appState.appName = 'name 2'
      },
      changeAppNameRaw() {
        raw.appStateRaw.appName = 'name 1'
        console.log(raw.appStateRaw);
      },
      log(l: any) {
        console.log(l);
      }
    };

    /**
     * 通过对toRaw的测试
     *  1. 仅对 reactive 或者 readonly有效，即源码中reactive()的，readonly，shallowReactive，shallowReadonly都是调用了reactive，只是不同的配置项
     *  2. 依然会改变值，只是不更新视图，当视图被更新的时候，会把这个值更新上去，例如 countRaw点击了addARaw，再点击 addA，原本 a为1，点击完成后，a直接更新为3，所以使用toRaw的时候要注意累加之类的。
     *  3. 不会马上更新prop，除非更新视图，和上面一样。
     *  4. markRaw和toRaw都符合上述三点。
     */
    const raw = {
      appStateRaw: toRaw(that.appState),
      propValueRaw: toRaw(that.propValue),
      countRaw: toRaw(that.count),
    };

    const test = {
      a: 1,
      b: 2,
      c: 3,
    }

    onMounted(() => {
      // console.log(arg);
      // console.log(useRouter());
      const route = getCurrentInstance()?.proxy?.$route
      // console.log(route);
      // console.log('mounted!')
    });
    onUpdated(() => {
      // console.log('updated!')
    });
    onUnmounted(() => {
      // console.log('unmounted!')
    });

    return {
      ...raw,
      ...that,
      ...methods, 
      test, // 使用这种方法在template里也不会有提示，神奇。
    };
  },
}); 
</script>

<style lang="scss" scoped>
.home {
  float: right;
  width: 99%;
}

.home > div{
  float: left;
  width: 30%;
  margin: 1.5%;
  border: 0.5px solid #cdcdcd;
  padding: 10px 0 0 0;
  height: 150px;
}
</style>